<template>
  <button
    :class="cn(buttonVariants({ color, visual, size, modifier }))"
    :disabled="loadingThrottled"
  >
    <slot v-if="!loadingThrottled" name="icon">
      <span v-if="iconClass" :class="iconClass"></span>
    </slot>
    <span v-else class="loading loading-spinner"></span>
    <slot></slot>
  </button>
</template>
<script setup lang="ts">
import { toRef } from "vue";
import { refThrottled } from "@vueuse/core";
import { cva } from "class-variance-authority";
import { cn } from "@/components/utils";
import type { Size, ButtonColor, ButtonVisual, ButtonModifier } from "./types";

interface Props {
  color?: ButtonColor;
  visual?: ButtonVisual;
  size?: Size;
  modifier?: ButtonModifier;
  iconClass?: string;
  loading?: boolean;
}

const buttonVariants = cva("btn gap-2", {
  variants: {
    color: {
      primary: "btn-primary",
      neutral: "btn-neutral",
      secondary: "btn-secondary",
      accent: "btn-accent",
      ghost: "btn-ghost",
      info: "btn-info",
      success: "btn-success",
      warning: "btn-warning",
      error: "btn-error",
    },
    visual: {
      outline: "btn-outline",
      dash: "btn-dash",
      soft: "btn-soft",
      ghost: "btn-ghost",
      link: "btn-link",
    },
    size: {
      xs: "btn-xs",
      sm: "btn-sm",
      md: "btn-md",
      lg: "btn-lg",
      xl: "btn-xl",
    },
    modifier: {
      wide: "btn-wide",
      block: "btn-block",
      square: "btn-square",
      circle: "btn-circle",
    },
  },
  defaultVariants: {},
});

const props = defineProps<Props>();

const loadingThrottled = refThrottled(
  toRef(() => props.loading),
  500
);
</script>
